package data;

import data.tileables.Resources;
import data.tileables.Structure;

/**************************************************************************************
 * Author(s): Changmin Bae, Eric Martin-Taylor
 * Datastructure to store HarvestNodes which store Resources
 **************************************************************************************/
public class StructLinkedList {

	HarvestNode first;
	HarvestNode last;
	int amount, type;
	final int FOOD =1,	METAL = 2, POWER = 3;
	
	public StructLinkedList(int _type){
		amount = 0;
		first = null;
		last = null;
		type = _type;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae, Eric Martin-Taylor
	 * Adds a tile to be harvested. Assumes tile is correct
	 **************************************************************************************/
	public void addResource(Resources temp, Structure struct){
		
		if(this.containsResource(temp))
		{
			System.out.println("Contains resource already");
			return;
		}

		if(!temp.assignStructure(struct))
		{
			System.out.println("Assigned to a structure");
			return;
		}

		amount++;
		HarvestNode x = new HarvestNode(temp, type);
		
		if(amount == 1){
			first = x;
			last = x;
		}
		else{
			last.next(x);
			x.previous(last);
			last = x;
		}
		
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor, Changmin Bae
	 * Figures out if the structure contains a tile already
	 **************************************************************************************/
	public boolean containsResource(Resources temp){
		
		HarvestNode node = first;
		while(node!= null)
		{
			if(node.equals(temp))
				return true;
			else if(node.hasNext()){
				node = node.next();
			}
			else
				break;		
		}
		return false;
	}

	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * Removes a tile/resource from the list
	 **************************************************************************************/
	public boolean remove(Resources temp){
		HarvestNode firstNode = first;
		
		while(firstNode != null){
			if(firstNode.equals(temp)){
				firstNode.remove();
				amount--;
				return true;
			}
			else if(firstNode.hasNext()){
				firstNode = firstNode.next();
			}
			else
				break;
		}
		
		return false;
	}


	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor, Changmin Bae
	 * harvests the tile as much as possible based on the number of workers
	 **************************************************************************************/
	public int harvest(){

		int harvest=0;
		HarvestNode node = first;
		
		while(node != null){
			if(node!= null)	
				harvest += node.harvest();
			else
				break;
			node = node.next();
		}
		return harvest;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae, Eric Martin-Taylor
	 * Assigns a worker to the selected tile
	 **************************************************************************************/
	public boolean assignWorkers(int num, Resources tile){
		HarvestNode firstNode = first;
		
		while(firstNode != null){
			if(firstNode.resource == tile){
				firstNode.assignWorkers(num);
				return true;
			}
			else if(firstNode.hasNext()){
				firstNode = firstNode.next();
			}
			else
				break;
		}
		System.out.println("StructLinkedList assign Workers returned false");
		return false;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae, Eric Martin-Taylor
	 * removes workers from the given tile*
	 * 		-1 = tile not found*
	 * 		> -1 = amounts of workers removed*
	 **************************************************************************************/
	public int unassignWorkers(int num, Resources tile){
		HarvestNode firstNode = first;

		while(firstNode != null)
		{
			if(firstNode.getResource() == tile)
			{
				if(firstNode.resource.getWorkerCount() == 0)
				{
					first = firstNode.next();
					amount--;
				}
				return firstNode.unassignWorkers(num);
			}
			firstNode = firstNode.next();
		}		
		return -1;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * removes and unassigns all workers and returns number of workers removed
	 **************************************************************************************/
	public int unassignAllWorkers()
	{
		HarvestNode firstNode = first;
		int toReturn = 0;
		while(firstNode != null)
		{
			toReturn += firstNode.unassignWorkers(firstNode.resource.getWorkerCount());
			if(firstNode.resource.getWorkerCount() == 0)
			{
				first = firstNode.next();
				amount--;
			}
			firstNode = firstNode.next();
		}
		return toReturn;
	}
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor, Changmin Bae
	 * Kills off the tile and do everything about it
	 **************************************************************************************/
	public void die(){
		HarvestNode node = first;
		
		while(node!= null)
			node.die();
	}

	public int unassign(){
		HarvestNode node = first;
		int amount=0;
		
		while(node != null)
			amount += node.remove();
		
		return amount;	
	}
}
